﻿using ATEC.ATCore;
using ATEC.ATDataCoreNET;
using ATEC.ATDataCoreNET.ATObjects;
using ATEC.GeometryNET;
using DynamicButtons;
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media.Media3D;
using System.Xml.Linq;

namespace ObjectExample
{
    /// <summary>
    /// 类名：ATObjectExample
    /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/创建
    /// 功能：展示如何基于玄镜图形平台将几何对象（CurveSet）转换为平台对象（ATObject）。
    /// 关键类及说明：
    ///     - ATObject：平台对象基类，代表图形平台中的任意图形实体。
    ///     - CurveSet：曲线集合，用于创建几何形状。
    ///     - GeometryToATObject：几何对象与平台对象之间的转换工具类。
    /// </summary>
    public class ATObjectExample
    {
        /// <summary>
        /// 平台对象示例，指向一个线段对象，类型为 CurveSet。
        /// 说明：用于存储通过几何转化生成的 ATObject。
        /// </summary>
        private ATObject cvObj = null; // 存储平台对象实例，初始化为 null

        /// <summary>
        /// 平台对象颜色标识。
        /// 说明：用于设置或表示生成对象的颜色属性。
        /// </summary>
        private uint objColor = 1; // 平台对象颜色标识，默认值为 1

        /// <summary>
        /// 方法名：CreateATObject_Line
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/创建
        /// 功能：将几何曲线集合（CurveSet）转换为平台对象（ATObject）。
        /// 参数：无
        /// 返回值：ATObject，表示基于几何数据生成的线段平台对象。
        /// </summary>
        private ATObject CreateATObject_Line()
        {
            // 定义比例因子，用于调整曲线尺寸
            double dSacle = 1.0; // 比例因子，默认值为 1.0

            // 定义起点坐标（0, 0, 0）
            var p1 = new ATEC.GeometryNET.XPoint3d(0, 0, 0); // 起点，位于原点

            // 定义终点坐标，乘以比例因子后为 (10000, 10000, 10000)
            var p2 = new ATEC.GeometryNET.XPoint3d(1e4 * dSacle, 1e4 * dSacle, 1e4 * dSacle); // 终点

            // 创建点集合，用于生成线段
            List<XPoint3d> listPts = new List<XPoint3d> { p1, p2 }; // 点集合，包含起点与终点

            // 基于点集合创建 CurveSet 对象，设置边界类型为 Open（开放边界），并禁用闭合属性
            CurveSet cv = CurveSet.CreateLinear(listPts, CurveSet.BoundaryType.Open, false); // 生成线段几何对象

            // 调用 GeometryToATObject 工具类，将 CurveSet 转换为 ATObject
            // 参数：
            //   Session.Entity.GetActiveATScenes()：获取当前活动的图形场景。
            //   cv：待转换的 CurveSet 几何对象。
            //   null：附加数据为空。
            var x = GeometryToATObject.ToObject(Session.Entity.GetActiveATScenes(), cv, null); // 几何转平台对象

            // 返回生成的 ATObject
            return x; // 返回平台对象
        }

        /// <summary>
        /// 方法名：ExtendLength
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/操作
        /// 功能：对现有的 ATObject 平台对象进行检查并延长其线段长度。
        /// 参数：无
        /// 返回值：无
        /// </summary>
        private void ExtendLength()
        {
            // 检查并初始化平台对象
            if (cvObj == null || cvObj.IsDeleted || !cvObj.IsValid) // 检查对象是否为空、已被删除或无效
            {
                cvObj = CreateATObject_Line(); // 如果无效或不存在，则重新创建线段平台对象
                cvObj.AddToScene(); // 将新创建的对象添加到场景中
            }
            else // 如果对象有效
            {
                // 从现有的 ATObject 中提取 CurveSet 几何对象
                ATEC.GeometryNET.CurveSet curve = ATEC.ATDataCoreNET.ATObjects.CurvePathQuery.ObjectToCurveSet(cvObj); // 转换为几何曲线集合
                if (curve == null) // 如果提取失败，则直接返回
                {
                    return;
                }

                // 对 CurveSet 进行修改，延长线段
                XPoint3d s, e; // 定义起点和终点变量
                curve.GetStartEnd(out s, out e); // 获取当前线段的起点和终点

                XVector3d dir = new XVector3d(s, e); // 根据起点和终点构造向量表示方向
                dir.NormalizeInPlace(); // 归一化向量，确保方向一致且长度为 1
                e = e + dir * 0.5e4; // 按方向延长线段末点 0.5 米（5000 毫米）

                // 使用新起点和延长后的终点创建新的 CurveSet 对象
                curve = CurveSet.CreateLinear(new List<XPoint3d> { s, e }, CurveSet.BoundaryType.Open, false); // 创建新的线段几何对象

                // 将新几何对象转换为 ATObject 平台对象
                ATObject newObj = GeometryToATObject.ToObject(Session.Entity.GetActiveATScenes(), curve, null); // 几何对象转换为平台对象
                newObj.ReplaceInScene(cvObj); // 替换场景中的原有对象
            }
        }

        /// <summary>
        /// 方法名：Rotate
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/操作
        /// 功能：对线段对象进行旋转操作，以 Z 轴为基准旋转指定角度。
        /// 参数：无
        /// 返回值：无
        /// 关键类及说明：
        ///     - XTransform3d：三维几何变换类，用于定义旋转、平移、缩放等操作。
        ///     - TransformInfo：封装几何变换的具体信息，供平台对象使用。
        ///     - XAngle：角度类，支持角度值的定义与转换。
        /// </summary>
        private void Rotate()
        {
            // 检查并初始化平台对象
            if (cvObj == null || cvObj.IsDeleted || !cvObj.IsValid) // 检查对象是否为空、已被删除或无效
            {
                cvObj = CreateATObject_Line(); // 如果无效或不存在，则重新创建线段平台对象
                cvObj.AddToScene(); // 将新创建的对象添加到场景中
            }
            else // 如果对象有效
            {
                // 定义旋转的几何参数
                XPoint3d pt = ATEC.GeometryNET.XPoint3d.Zero; // 定义旋转的基点（坐标原点）
                XVector3d dir = XVector3d.UnitZ; // 定义旋转轴为 Z 轴
                XAngle angle = XAngle.FromDegrees(15); // 定义旋转角度为 15 度

                // 构造旋转变换
                XTransform3d trans = ATEC.GeometryNET.XTransform3d.FromRotationAroundLine(pt, dir, angle); // 创建以基点为中心、Z 轴为轴的旋转变换

                // 应用旋转变换到平台对象
                cvObj.ApplyTransform(new ATEC.ATDataCoreNET.TransformInfo(trans)); // 将变换信息应用到平台对象
                cvObj.ReplaceInScene(cvObj); // 更新平台对象在场景中的显示状态
            }
        }

        /// <summary>
        /// 方法名：ExtendAndRotate
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/操作
        /// 功能：将线段平台对象进行延长操作后，再进行绕 Z 轴旋转的复合操作。
        /// 参数：无
        /// 返回值：无
        /// 关键类及说明：
        ///     - ExtendLength()：负责延长线段长度的方法。
        ///     - Rotate()：负责绕 Z 轴旋转线段的方法。
        /// 说明：
        ///     该方法调用了两个独立的几何变换操作，按顺序先延长后旋转。
        /// </summary>
        private void ExtendAndRotate()
        {
            ExtendLength(); // 调用延长线段的方法，将当前线段延长
            Rotate(); // 调用旋转方法，绕 Z 轴对延长后的线段进行旋转
        }


        /// <summary>
        /// 方法名：SetColor
        /// 分类：玄镜BIM图形平台/C#开发/示例代码/平台对象/操作
        /// 功能：为线段平台对象设置颜色，每次调用会自动递增颜色值。
        /// 参数：无
        /// 返回值：无
        /// 关键类及说明：
        ///     - ObjectPropertiesSetter：提供平台对象属性设置功能的类。
        ///     - SetColor(uint color)：设置对象的颜色。
        ///     - Apply(ATObject obj)：将属性变更应用于目标对象。
        /// 说明：
        ///     本方法通过 ObjectPropertiesSetter 类修改平台对象颜色，并刷新其场景显示。
        /// </summary>
        private void SetColor()
        {
            ObjectPropertiesSetter setter = new ObjectPropertiesSetter(); // 创建属性设置器对象，用于修改平台对象属性
            setter.SetColor(objColor++); // 设置颜色为当前 objColor 值，并递增 objColor 以为下次调用做准备
            setter.Apply(cvObj); // 将颜色变更应用到当前平台对象 cvObj
            cvObj.ReplaceInScene(cvObj); // 刷新平台对象的显示以生效新的颜色
        }


        /// <summary>
        /// 功能：删除当前平台对象（cvObj），从场景中移除该对象。
        /// 关键类及说明：
        ///     cvObj: 平台对象实例，需确保其有效性才可执行删除操作。
        /// </summary>
        private void Delete()
        {
            // 判断当前平台对象 cvObj 是否有效且未删除
            if (cvObj != null && cvObj.IsValid)  // 如果平台对象存在且有效
            {
                cvObj.DeleteFromScene();  // 从场景中删除该平台对象
            }
        }


        public void Run()
        {
            ButtonsView v = new ButtonsView();

            v.AddButton("创建对象", (Object sender, RoutedEventArgs e) => {
                cvObj = CreateATObject_Line();
                cvObj.AddToScene();
            });

            v.AddButton("加长", (Object sender, RoutedEventArgs e) => {
                ExtendLength();
            });

            v.AddButton("旋转", (Object sender, RoutedEventArgs e) => {
                Rotate();
            });

            v.AddButton("加长并旋转", (Object sender, RoutedEventArgs e) => {
                ExtendAndRotate();
            });

            v.AddButton("变色", (Object sender, RoutedEventArgs e) => {
                SetColor();
            });

            v.AddButton("删除", (Object sender, RoutedEventArgs e) => {
                Delete();
            });
            v.Show();
        }
    }
}
